package com.zerone.dy.demomsg.webSocket;

import com.alibaba.fastjson.JSON;
import com.zerone.dy.demomsg.entity.Message;
import com.zerone.dy.demomsg.excpetion.JbMessageExcpetion;
import com.zerone.dy.demomsg.webSocket.config.WebSocketConfig;
import com.zerone.dy.demomsg.webSocket.constant.WebSocketConstant;
import com.zerone.dy.demomsg.webSocket.service.WebSocketSessionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;

@Slf4j
@ServerEndpoint(value = "/jbws",configurator = WebSocketConfig.class)
@Component
public class JbWebSocket {



    @OnOpen
    public void onOpen(Session session){
        String acNo = validateSession(session);
        WebSocketSessionService.sessionMap.put(acNo,session);
        log.info("{} 上线了,当前在线人数:{}",acNo,WebSocketSessionService.sessionMap.size());
    }

    @OnClose
    public void onClose(Session session){
        String acNo =sessionGetAcNo(session);
        if(acNo==null){
            closeSession(session);
        }
        WebSocketSessionService.removeSession(acNo);
        log.info("{} 下线了,当前在线人数:{}",acNo,WebSocketSessionService.sessionMap.size());
    }

    @OnMessage
    public void onMessage(String message,Session session)  {
        String acNo =sessionGetAcNo(session);
        log.info("服务端收到来自用户:{} 的消息:{}",acNo,message);
        Message messageObj = JSON.parseObject(message, Message.class);
        try {
            WebSocketSessionService.sendMsg(messageObj);
        } catch (JbMessageExcpetion e) {
            log.info("服务端处理来自用户:{} 的消息失败 ：{}",acNo,message);
            throw new RuntimeException(e);
        }
    }


    @OnError
    public void onError(Session session,Throwable error){
        String acNo =sessionGetAcNo(session);
        log.error(acNo+":webSocket 异常.",error);
    }

    private String validateSession(Session session) {
        String acNo =sessionGetAcNo(session);
        if(acNo==null){
            closeSession(session);
        }
        return acNo;
    }

    private String sessionGetAcNo(Session session){
        Object acNo = session.getUserProperties().get(WebSocketConstant.AC_NO);
        if(acNo==null || "".equals(acNo.toString())){
            return null;
        }
        return (String)acNo;
    }

    private void closeSession(Session session){
        try {
            session.close();
            log.error("权限验证失败,捂手失败.");
            throw new RuntimeException("握手失败");
        } catch (IOException e) {
            log.error("session close faild IOException.");
            throw new RuntimeException(e);
        }
    }
}
